package com.cloud.other;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author tangyuan2meicloud.com
 * @DATE 2021/7/5 9:20
 * @Desc
 * @Remarks
 */
//@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {
    public static final String REDIS_ROUTE_DEFINITION = "spring_gateway_route_definition";
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        List<RouteDefinition> routeDefinitions = new ArrayList<>();
        redisTemplate.opsForHash().values(REDIS_ROUTE_DEFINITION).stream().forEach(definition -> {
            RouteDefinition routeDefinition = JSON.parseObject(definition.toString(), RouteDefinition.class);
            routeDefinitions.add(routeDefinition);
        });
        return Flux.fromIterable(routeDefinitions);
    }
    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return route.flatMap(routeDefinition -> {
            redisTemplate.opsForHash().put(REDIS_ROUTE_DEFINITION,
                    routeDefinition.getId(),
                    JSON.toJSONString(routeDefinition));
            return Mono.empty();
        });
    }
    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return routeId.flatMap(routeDefinition -> {
            if (redisTemplate.opsForHash().hasKey(REDIS_ROUTE_DEFINITION, routeDefinition)) {
                redisTemplate.opsForHash().delete(REDIS_ROUTE_DEFINITION, routeDefinition);
                return Mono.empty();
            }
            return Mono.defer(() -> {
                return Mono.error(new Exception("routeDefinition not exist:routeId" + routeId));
            });
        });
    }
}
